#include "StdAfx.h"
#include ".\WF.h"

CWFObject::CWFObject()
{
}

CWFObject::~CWFObject()
{
	Clear();
}

void	CWFObject::Clear()
{
	// clear the vertices
	for( int i=0; i<NumVertices(); i++ )
	{
		CVertex *pV = m_vecVertices.at( i );
		delete pV;
		pV = NULL;
	}
	m_vecVertices.clear();

	// clear the edges
	for( int i=0; i<NumEdges(); i++ )
	{
		CEdge *pE = m_vecEdges.at( i );
		delete pE;
		pE = NULL;
	}
	m_vecEdges.clear();
}

int		CWFObject::NumVertices()
{
	return (int)m_vecVertices.size();
}

int		CWFObject::NumEdges()
{
	return (int)m_vecEdges.size();
}

// load from file
int		CWFObject::Load(char *filename)
{
	int ok = FALSE;
	FILE *fp;

	if( (fp = fopen (filename, "rt")) == NULL )
		return FALSE;

	ok = Load (fp);
	fclose (fp);

	return ok;
}


int		CWFObject::Load(FILE *fp)
{
	int ok = FALSE;
	int nv, ne;

	Clear();

	// for debugging
	CountElements( fp, nv, ne );

	if( ReadVertices(fp)  &&  ReadEdges(fp) )
		ok = TRUE;

	return ok;
}


int CWFObject::CountElements( FILE *fp, int& nv, int& ne )
{
	char *s;

	// count number of vertices
	// the former lines are vertices
	nv = 0;
	while(s = GetValidLine (fp))
	{
		int items, id;
		double d;

		items = sscanf(s,"%lg%lg%lg%d",&d,&d,&d,&id);
		assert(items == 4);
		nv++ ;
	}

	// count number of edges
	ne = 0;
	while(s = GetValidLine (fp))
	{
		int items, d;

		items = sscanf(s,"%d%d",&d,&d);
		assert( items== 2 );
		ne++;
	}

	fseek (fp, 0, SEEK_SET);

	return TRUE;
}


// discards comments and blank lines, calling callback if double pound
// (caller can save special info in these fields)
char	*CWFObject::GetValidLine (FILE *file)
{
	static char s[1024];

	int nLines = 0;
	int nValidLines = 0;

	while (fgets (s, sizeof(s), file))
	{
		char *pound;

		nLines++ ;

		if (s[0]  == '\n')
		{
			return NULL;
		}
		else if (pound = strchr (s, '#'))
		{
			if (s != pound)
			{
				*pound = '\0';
				return s;
			}
		}
		else
		{
			nValidLines++;
			return s;
		}
	}

	return NULL;
}


int			CWFObject::AddVertex(double x, double y)
{
	CVertex *pVert = new CVertex( x, y ) ;
	if( pVert )
	{
		m_vecVertices.push_back( pVert );
		return TRUE;
	}
	else
		return NULL;
}


int		CWFObject::ReadVertices (FILE *file)
{
	char *s;

	while( s = GetValidLine (file) )
	{
		double x,y,z=0.0;
		int id ;

		int items = sscanf(s,"%lg%lg%lg %d", &x,&y,&z,&id );
		assert( items == 4 );

		AddVertex(x, y);
	}

	return TRUE;
}


int		CWFObject::AddEdge(int v0, int v1)
{
	CEdge *pE = new CEdge( v0, v1 );
	if( pE )
	{
		m_vecEdges.push_back( pE );
		return TRUE;
	}
	else
		return FALSE;
}


int		CWFObject::ReadEdges(FILE *fp)
{
	char *s;

	while( s = GetValidLine(fp) )
	{
		int v0, v1;

		int items = sscanf(s,"%d%d",&v0,&v1);
		assert( items == 2 );

		AddEdge(v0, v1);
	}

	return TRUE;
}
